{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Problem 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "44.99999999999996\n"
     ]
    }
   ],
   "source": [
    "def f(d, delta, Ein):\n",
    "    return (d + 1) / (1 - Ein / (delta ** 2))\n",
    "\n",
    "print(f(8, 0.1, 0.008))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Problem 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签\n",
    "plt.rcParams['axes.unicode_minus']=False #用来正常显示负号\n",
    "\n",
    "#构造损失函数\n",
    "def e1(s):\n",
    "    if s > 0:\n",
    "        return 0\n",
    "    else:\n",
    "        return 1\n",
    "\n",
    "def e2(s):\n",
    "    return max(0, 1 - s)\n",
    "\n",
    "def e3(s):\n",
    "    t = max(0, 1 - s)\n",
    "    return t ** 2\n",
    "\n",
    "def e4(s):\n",
    "    return max(0, -s)\n",
    "\n",
    "def e5(s):\n",
    "    return 1 / (1 + np.exp(s))\n",
    "\n",
    "def e6(s):\n",
    "    return np.exp(-s)\n",
    "\n",
    "x = np.arange(-1, 1, 0.01)\n",
    "\n",
    "y1 = [e1(i) for i in x]\n",
    "y2 = [e2(i) for i in x]\n",
    "y3 = [e3(i) for i in x]\n",
    "y4 = [e4(i) for i in x]\n",
    "y5 = [e5(i) for i in x]\n",
    "y6 = [e6(i) for i in x]\n",
    "\n",
    "plt.plot(x, y1, label='e1')\n",
    "plt.plot(x, y2, label='e2')\n",
    "plt.plot(x, y3, label='e3')\n",
    "plt.plot(x, y4, label='e4')\n",
    "plt.plot(x, y5, label='e5')\n",
    "plt.plot(x ,y6, label='e6')\n",
    "plt.legend()\n",
    "plt.title('损失函数比较')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Problem 7"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.09413996 0.00178911]\n",
      "2.8250003566832635\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "from numpy.linalg import inv\n",
    "\n",
    "def E(u,v):\n",
    "    return np.exp(u) + np.exp(2 * v) + np.exp(u * v) + u * u - 2 * u * v + 2 * v * v - 3 * u - 2 * v\n",
    "\n",
    "def partial(point):\n",
    "    u = point[0]\n",
    "    v = point[1]\n",
    "    pu = np.exp(u) + v * np.exp(u * v) + 2 * u - 2 * v - 3\n",
    "    pv = 2 * np.exp(2 * v) + u * np.exp(u * v) - 2 * u + 4 * v - 2\n",
    "    return np.array([pu, pv])\n",
    "\n",
    "def dpartial(point):\n",
    "    u = point[0]\n",
    "    v = point[1]\n",
    "    puu = np.exp(u) + np.exp(u * v) * (v ** 2) + 2\n",
    "    pvv = 4 * np.exp(2 * v) + np.exp(u * v) * (u ** 2) + 4\n",
    "    puv = np.exp(u * v) * (1 + u * v) - 2\n",
    "    return np.array([[puu, puv], [puv, pvv]])\n",
    "\n",
    "\n",
    "####Problem 7\n",
    "point = np.zeros(2)\n",
    "eta = 0.01\n",
    "\n",
    "for i in range(5):\n",
    "    point -= eta * partial(point)\n",
    "    \n",
    "print(point)\n",
    "print(E(point[0], point[1]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Problem 10"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.61181172 0.07049955]\n",
      "2.360823345643139\n"
     ]
    }
   ],
   "source": [
    "####Problem 10\n",
    "point = np.zeros(2)\n",
    "eta = 0.01\n",
    "\n",
    "for i in range(5):\n",
    "    point -= inv(dpartial(point)).dot(partial(point))\n",
    "\n",
    "print(point)\n",
    "print(E(point[0], point[1]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Problem 11"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-15.999999999999998\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "X = np.array(\n",
    "        [[1, 1, 1, 1, 1, 1],\n",
    "         [1, 1, -1, 1, -1, 1],\n",
    "         [1, -1, -1, 1, 1, 1],\n",
    "         [1, -1, 1, 1, -1, 1],\n",
    "         [1, 0, 0, 0, 0, 0],\n",
    "         [1, 1, 0, 1, 0, 0]]\n",
    "        )\n",
    "print(np.linalg.det(X))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Problem 13"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from numpy.linalg import inv\n",
    "from sklearn.preprocessing import PolynomialFeatures\n",
    "plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签\n",
    "plt.rcParams['axes.unicode_minus']=False #用来正常显示负号\n",
    "\n",
    "#产生n组点\n",
    "def generate(n, p=0.1):\n",
    "    X = np.random.uniform(-1, 1, size=(n, 2))\n",
    "    y = np.sign(np.sum(X ** 2, axis=1) - 0.6)\n",
    "    #翻转\n",
    "    P = np.random.uniform(0, 1, n)\n",
    "    y[P < p] *= -1\n",
    "    #产生数据\n",
    "    return X, y\n",
    "\n",
    "#数据数量\n",
    "n = 1000\n",
    "#实验次数\n",
    "m = 1000     \n",
    "X, y = generate(n)\n",
    "\n",
    "plt.scatter(X[y>0][:, 0], X[y>0][:, 1], s=1)\n",
    "plt.scatter(X[y<0][:, 0], X[y<0][:, 1], s=1)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.505447\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXYAAAEFCAYAAAD36MwKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvOIA7rQAAE4hJREFUeJzt3XuQpVV97vHv44AJN4FIZ7gYMiEhWomCyWmuByodM2AAEzjGBCupJCaaybEMdVLnUk5MTgJGLEMST3GMYo2BgpDSlBrLywGDGpliIkToGW7jhajDII6gjRhGIiEn1O/8sd85btq+7N69uze95vup2tXvXu9lrXfNnmevXnu/b6eqkCS141njboAkabQMdklqjMEuSY0x2CWpMQa7JDXGYJekxhjsa1SSVyV5IsnDfY8f6Fv/gSRnrmD9Ax0/yaVJLl2pdgxY/0NJvprkhHG1Y61JclqSzyf5epL/Me72aGkM9rXtQ1V1dN/jwX0rqurlVXXrSlU81/GTbEjyqpWqM8mLk1y0hO2PAP4rcALwI8BDQ9a7oue1QL1HJPnd1a63sxm4vKq+H7hmTG3QkAx2jdIG4FUrePwXAwMHO3AE8GhVPVFV366qJ4asdwMre17zOQIYV7AfCTwIUFXfGFMbNCSDvVFJtiaZ6nt+aZL/leTvknwjyZUL7HtAkm8meVaSHd20z+8kuWKB428DPgCc2U0LvavvkIfPrrc79p8n2ZPk7iSndOXX9o+Ok1T3czdwJXBxd/w/XOT83w3cAfxAt/3f9a17Q5IvJ3kgyc/1tWdLN2XzxSTnLnRes6eYkuxOsqFv+SVJbk5yXd82v5FkVzc19FvLaP/WJK9I8sEkn+wr/8/dee1J8vqubKrb/s+TPJLkliQHdet+O8mD3XTLm7qyC5M8DJwJfKCr+/ndunO76ZkHk7yhr95rk7w2yTVJvtBX9n+6tvxpkvuTbFnonDVCVeVjDT7ojSCfAB7uHttmrd8KTPU9vxR4DDgFOA54Evi+BY5/O73piw8DVwD/G3jlfMfvyqaArbPK5qwXeA3w98D3Ai8BdgPfA1wLvKpv/5p1ztcuoY82ALtnlZ3X1XsI8Hx60zMHAqcB7wcOAE4Hbh/gvC7te74b2NC3vAM4CzisK/tx4N7u3NcDe4D1S21/X9//E/DzwOFd2fcCnwKOBQ4GZoBDu7Y/CfxOd553Af+p22cv8MJu3/fta+s8r5/n0nudnQQcDtwNnN+tuxb4MvDqfa+pruwvu3rvo/fb1q5x/7/ZXx4HoLXsQ1X1yiVs/5GqugOgG5U9B3h0nm130AvB7cCJwATwF0O2c656zwPeVVX/CnwyyWPAi/p3SpIh61vIRnpvMl/qnh8MHFtVn07yVuCNwDn0zncpZrf1iqr6h77nL6E31//Z7vlB9N5YvrbEeva5pqo+vO9JVf1rkl8DfhU4m94byFHd6q8Bb6+qSnI3vWAG+AfgcuCDwGur6lsL1HcmcFdV3QO9ETlwPnBjt/7Gqrp61j63AU/RGyT8M84QrBo7ev/ypb7lxe7+toPefPYX6I1ij+mWR1nv7OXZbTpuyPoWEnofCh5dVUcDxwN7kvwK8HbgTnqjzMEPmBxAbxTe7x/nqPev+up93hzbLMXT9k3yw8At9N6o/xvd/Hjn/uqG0Ty9j3+e3m9izwd2JlnszWyhf6+5zuWpWT+1Sgz2/ctSbuW5g94o85+Afwe+2RcO83kEeF6SdUmOTLJugXo/Crw6yfck+Sl6HxTupDc9sO9rm5fMcfwfBEhyFMP5BPBLSZ6T5Fh6bzpHAGcANwEfAi4c4Lz627mJ3jTSQj4JnJfk6CSH0ZvK+LFF9vkG8NwkB3ePgxbY9ifoTQFdQy+on9e37rv6P8nB9Pp7B/CHwOP0pt7mcyvw4iQvTPIc4Nfp/RvqGchgX9suzNO/x/4LIzz2vcD/pRfsX6A3kl1QVe2kF5x76IXGsxfY/Jqujl30Ro2/WFVPAu8Cfrn7sHD3rH1uAh5L8rWuniWrqhvpTT3spDcnfUlVPUJvTviXgPu7dk8kOXyB8/obYDLJx+iN1h9YpN6dwB/Tm574LL2pkbsW2edbwJ/Qe/O5n95vTfPZ1x9fA17Zbf+jCxz728A76P0bPAhsozdlMt/236AX5u8HPgO8r+tLPQNl8UGYJGktccQuSY0x2CWpMQa7JDXGYJekxozlAqWjjjqqNmzYMI6qJWnN2r59+yNVtejFc2MJ9g0bNjA9PT2OqiVpzUqy4Ndq93EqRpIaY7BLUmMMdklqjMEuSY0x2CWpMQa7JDXGYJekxhjsktQYg12SGuPfPNWCNmy+YSz17n7LBWOpV2qBI3ZJaozBLkmNMdglqTEGuyQ1ZqBgT7I+ybZu+bIkW7vH55P8XpLjknylr3zR+wVLklbGot+KSXIkcB1wCEBV/VHfuvcDfwWcBlxeVVetUDslSQMaZMT+FHAxsLe/MMkpwFeqag9wOvCaJDuSvHn0zZQkDWrRYK+qvVX12Byr/gvwtm75o8AUcApwRpKTZm+cZFOS6STTMzMzy2iyJGkhQ12glOQI4Pur6ktd0a1V9WS37k7gROCe/n2qaguwBWBycrKGbrH2C+O6MAq8OEpr37DfirkQuLHv+U1JjklyMHAusHPZLZMkDWXYYH8pcEvf88uAm4F/BN5ZVfctt2GSpOEMPBVTVVN9y788a93NwAtG1yxJ0rC8QEmSGmOwS1JjDHZJaozBLkmNMdglqTEGuyQ1xmCXpMYY7JLUGINdkhpjsEtSYwx2SWqMwS5JjTHYJakxBrskNWaov6AkqR3+tar2OGKXpMYY7JLUGINdkhpjsEtSYwx2SWqMwS5JjRko2JOsT7KtWz4uyVeSbO0eE1351UluS/IHK9lgSdLCFg32JEcC1wGHdEWnAZdX1VT3mEnycmBdVZ0BnJDkxJVrsiRpIYOM2J8CLgb2ds9PB16TZEeSN3dlU8B7u+WPAWfNPkiSTUmmk0zPzMwsr9WSpHktGuxVtbeqHusr+ii9ID8FOCPJSfRG83u69Y8C6+c4zpaqmqyqyYmJiWU3XJI0t2FuKXBrVT0JkORO4ETgceCgbv2h+KGsJI3NMAF8U5JjkhwMnAvsBLbznemXk4Hdo2meJGmphhmxXwbcDPwb8M6qui/JQ8C2JMcC59Gbh5ckjcHAwV5VU93Pm4EXzFq3N8kUcA5wxaw5eUnSKhrZbXur6pt855sxkqQx8UNOSWqMwS5JjTHYJakxBrskNcZgl6TGGOyS1BiDXZIaY7BLUmMMdklqzMiuPJW0PBs23zDuJqgRjtglqTEGuyQ1xmCXpMYY7JLUGINdkhpjsEtSYwx2SWqMwS5JjTHYJakxAwV7kvVJtnXLxyfZmuSTSbak57gkX+nKtyaZWNlmS5Lms+gtBZIcCVwHHNIV/Tbw2qr6XJKPAi8CfgS4vKquWrGWSpIGMsiI/SngYmAvQFX9flV9rlv3XOAR4HTgNUl2JHnzirRUkjSQRUfsVbUXIMnTypNcDHymqr7ajdz/GPg28IkkJ1XVPbO23wRsAjj++ONH03ppBXgzLq11Q314muQE4L8Dv9sV3VpV36qqp4A7gRNn71NVW6pqsqomJyacgpeklbLkYO/m3N8D/GZVPdYV35TkmCQHA+cCO0fYRknSEgxzP/bNwPHA27rpmT8CLgNuBv4NeGdV3TeyFkqSlmTgYK+qqe7n64HXz7HJC0bUJknSMniBkiQ1xmCXpMYY7JLUGINdkhpjsEtSYwx2SWqMwS5JjTHYJakxBrskNcZgl6TGGOyS1BiDXZIaM8zdHSVpJMb1R012v+WCsdS7WhyxS1JjDHZJaozBLkmNMdglqTEGuyQ1xmCXpMYY7JLUGINdkhozULAnWZ9kW7d8YJKPJPlUkt+cr0ySNB6LBnuSI4HrgEO6okuA7VX1H4FXJDlsnjJJ0hgMMmJ/CrgY2Ns9nwLe2y3fAkzOU/Y0STYlmU4yPTMzs4wmS5IWsmiwV9Xeqnqsr+gQYE+3/Ciwfp6y2cfZUlWTVTU5MTGxvFZLkuY1zIenjwMHdcuHdseYq0ySNAbDBPB24Kxu+WRg9zxlkqQxGOa2vdcBNyY5G/gx4NP0pmFml0mSxmDgEXtVTXU/HwDOAT4FbKyqp+YqW4G2SpIGMNQf2qiqr/Kdb8HMWyZJWn1+yClJjTHYJakxBrskNcZgl6TGGOyS1BiDXZIaY7BLUmMMdklqjMEuSY0x2CWpMQa7JDXGYJekxhjsktQYg12SGmOwS1JjDHZJaozBLkmNMdglqTEGuyQ1Zqi/eZrktcDF3dMjgO30/pj1rq7skqq6d/nNkyQt1bB/zPoq4CqAJG8DrgceqarXj7BtkqQhLGsqJslxwHpgEnhZktuTXJ3ku94wkmxKMp1kemZmZjnVSpIWsNw59tfRG7nfAWysqlOBA4HzZ29YVVuqarKqJicmJpZZrSRpPkMHe5JnAT8NbAXuqaqHulXTwInLb5okaRjLGbGfDXy6qgq4PsnJSdYBFwF3j6R1kqQlG+rD085LgVu65TcC7wYCfLiqPrHchkmShjN0sFfVG/qWdwInjaRFkqRl8QIlSWqMwS5JjTHYJakxBrskNcZgl6TGGOyS1BiDXZIaY7BLUmMMdklqjMEuSY0x2CWpMQa7JDXGYJekxizntr1aJRs23zDuJkhaQxyxS1JjDHZJaozBLkmNMdglqTEGuyQ1xmCXpMYY7JLUmCV/jz3JAcCu7gFwCfAK4Hzg9qp63eiaJ0laqmFG7CcB76mqqaqaAp4NnAWcCnw9ycYRtk+StETDBPvpwMuS3J7kauBngL+tqgJuAs6ea6ckm5JMJ5memZkZvsWSpAUNE+x3ABur6lTgQOAgYE+37lFg/Vw7VdWWqpqsqsmJiYmhGitJWtww94q5p6qe7Jan+U64AxyKH8hK0lgNE8LXJzk5yTrgIuAQenPsACcDu0fUNknSEIYZsb8ReDcQ4MPAm4BtSa4EfrZ7SJLGZMnBXlU76X0z5v/rvglzAXBlVd0/orZJkoYwkvuxV9UTwPtHcSxJ0vL4QackNcZgl6TGGOyS1BiDXZIaY7BLUmMMdklqjMEuSY0x2CWpMSO5QEmS1pINm28YW92733LBitfhiF2SGmOwS1JjDHZJaozBLkmNMdglqTEGuyQ1xmCXpMYY7JLUGINdkhpjsEtSY5Z8S4EkhwN/A6wD/gW4GPgisKvb5JKqundkLZQkLckwI/ZfAd5aVecCDwObgfdU1VT3MNQlaYyWHOxV9Y6q+nj3dAL4d+BlSW5PcnWSOX8LSLIpyXSS6ZmZmWU0WZK0kKHn2JOcARwJfBzYWFWnAgcC58+1fVVtqarJqpqcmJgYtlpJ0iKGum1vku8D3gb8AvBwVT3ZrZoGThxR2yRJQ1jyiD3Js4H3Ab9XVQ8A1yc5Ock64CLg7hG3UZK0BMNMxbwa+Eng95NsBT4DXA/cBdxWVZ8YXfMkSUu15KmYqroKuGpW8WWjaY4kabm8QEmSGmOwS1JjDHZJaozBLkmNMdglqTFDXaC0v9qw+YZxN0GSFuWIXZIaY7BLUmMMdklqjMEuSY0x2CWpMQa7JDXGYJekxhjsktQYg12SGmOwS1JjDHZJaozBLkmNMdglqTFr7u6O3mFRkhbmiF2SGjPSYE9ydZLbkvzBKI8rSRrcyII9ycuBdVV1BnBCkhNHdWxJ0uBGOcc+Bby3W/4YcBbwhX0rk2wCNnVPH09y3wjrHoWjgEfG3YhnKPtmfvbN/OybOeRPgOH75gcH2WiUwX4IsKdbfhT4yf6VVbUF2DLC+kYqyXRVTY67Hc9E9s387Jv52TfzW+m+GeUc++PAQd3yoSM+tiRpQKMM3+30pl8ATgZ2j/DYkqQBjXIq5oPAtiTHAucBp4/w2KvhGTtN9Axg38zPvpmffTO/Fe2bVNXoDpYcCZwD3FJVD4/swJKkgY002CVJ4+cHnJLUmP0i2Ae9IjbJ+iR3LnW/tWyYvklyQJIvJ9naPV60Oq1dXYv1zXz9kOSyJHckefvqtnj1LKNv7uorO2d1W716lvD/6h1Jfm6p+y2m+WBf4hWxf0b3lc394UraYfsGOAl4T1VNdY97V7qtq23AvvmufkjyH+h9O+xU4OtJNq5is1fFMvrmucDn+8o+vqoNXyWD/r9KcjZwdFV9ZCn7DaL5YGfuK2K/S5KXAP8C7PvQd6D91rgphuub04GXJbm9G2GsubuEDmCKxftmrn74KeBvq/fh1U3A2avR2FU2xXB9cxpwapJbk3wwyWGr09xVN8Ui/ZPkQOBdwO4kFw6636D2h2CffUXs+tkbJHk28D+BzUvZrwHD9s0dwMaqOhU4EDh/hds5DoP8+8/VD75ueubqm13AS6vqTOAe4DdWoa3jMEj//BrwWeAKem92lwy430D2h2Af5IrYzcA7quqfl7jfWjds39xTVQ91y9NAc9NUDNY3c/WDr5ueufpmF/DFWWUtGqR/fgLY0n0t/K+Bnx5wv4G0+KKbbZArYjcCr0uyFXhxkr8ccL+1bti+uT7JyUnWARcBd69CW1fbIH0zVz/4uumZq28uB/Z9UPgK2nzdwGD980XghG55EnhgwP0GU1VNP4Dn0HsBvRX4XNdhb1pg+63z7Hf4uM/lGdQ3L6T3q/S9wOXjPo9x9c1c/UBvsPQp4ErgPuCHxn0uz6C+OQb4NLCT3vzygeM+lzH2z2HA+4BbgNuA40aZOfvFBUrDXhG7P1xJuz+c47CW8bo5CLgA2FFVu1aqfePk62Zh486c/SLYJWl/sj/MsUvSfsVgl6TGGOyS1BiDXZIaY7BLUmP+H/r7RGV2pyUuAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#Problem 13\n",
    "Ein = np.array([])\n",
    "for i in range(m):\n",
    "    X, y = generate(n)\n",
    "    X = np.c_[np.ones(n), X]\n",
    "\n",
    "    w = inv(X.T.dot(X)).dot(X.T).dot(y)\n",
    "\n",
    "    ein = np.mean(np.sign(X.dot(w) * y) < 0 )\n",
    "    Ein = np.append(Ein, ein)\n",
    "\n",
    "print(np.average(Ein))\n",
    "plt.hist(Ein)\n",
    "plt.title('Ein without feature transform')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "w3的均值-0.011925513186691142\n",
      "w的均值[-0.99853694  0.00427153  0.00298056  1.55328108 -0.01192551  1.5622585 ]\n"
     ]
    }
   ],
   "source": [
    "#Problem 14\n",
    "#多项式转换器\n",
    "poly = PolynomialFeatures(2)\n",
    "W = []\n",
    "Eout = np.array([])\n",
    "Ein = np.array([])\n",
    "for i in range(m):\n",
    "    X, y = generate(n)\n",
    "    X_poly = poly.fit_transform(X)\n",
    "    \n",
    "    w_poly = inv(X_poly.T.dot(X_poly)).dot(X_poly.T).dot(y)\n",
    "\n",
    "    ein = np.mean(np.sign(X_poly.dot(w_poly) * y) < 0)\n",
    "    Ein = np.append(Ein, ein)\n",
    "    #测试数据\n",
    "    X_test, y_test = generate(n)\n",
    "    X_test_poly = poly.fit_transform(X_test)\n",
    "    eout = np.mean(np.sign(X_test_poly.dot(w_poly) * y_test) < 0)\n",
    "    Eout  = np.append(Eout, eout)\n",
    "    \n",
    "    #记录w\n",
    "    W.append(w_poly)\n",
    "\n",
    "W = np.array(W)\n",
    "w3 = W[:, 4]\n",
    "plt.hist(w3)\n",
    "plt.title('w3')\n",
    "plt.show()\n",
    "print(\"w3的均值{}\".format(w3.mean()))\n",
    "print(\"w的均值\" + str(np.mean(W, axis=0)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.125842\n"
     ]
    }
   ],
   "source": [
    "#Problem 15\n",
    "plt.hist(Eout)\n",
    "plt.title('Eout with feature transform')\n",
    "plt.show()\n",
    "print(Eout.mean())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Problem 18"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.475\n",
      "[[ 0.01878417]\n",
      " [-0.01260595]\n",
      " [ 0.04084862]\n",
      " [-0.03266317]\n",
      " [ 0.01502334]\n",
      " [-0.03667437]\n",
      " [ 0.01255934]\n",
      " [ 0.04815065]\n",
      " [-0.02206419]\n",
      " [ 0.02479605]\n",
      " [ 0.06899284]\n",
      " [ 0.0193719 ]\n",
      " [-0.01988549]\n",
      " [-0.0087049 ]\n",
      " [ 0.04605863]\n",
      " [ 0.05793382]\n",
      " [ 0.061218  ]\n",
      " [-0.04720391]\n",
      " [ 0.06070375]\n",
      " [-0.01610907]\n",
      " [-0.03484607]]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "def preprocess(X):\n",
    "    \"\"\"\n",
    "    添加偏置项\n",
    "    \"\"\"\n",
    "    n = X.shape[0]\n",
    "    return np.c_[np.ones(n), X]\n",
    "\n",
    "#数据读入\n",
    "data_train = np.genfromtxt(\"hw3_train.dat\")\n",
    "X_train = data_train[:, :-1]\n",
    "y_train = data_train[:, -1].reshape(-1, 1)\n",
    "X_train = preprocess(X_train)\n",
    "data_test = np.genfromtxt(\"hw3_test.dat\")\n",
    "X_test = data_test[:, :-1]\n",
    "y_test = data_test[:, -1].reshape(-1, 1)\n",
    "X_test = preprocess(X_test)\n",
    "\n",
    "#定义函数\n",
    "def sigmoid(s):\n",
    "    return 1 / (np.exp(-s) + 1)\n",
    "\n",
    "def gradient(X, w, y):\n",
    "    temp1 = - X.dot(w) * y\n",
    "    temp2 = sigmoid(temp1)\n",
    "    temp3 = - X * y\n",
    "    grad = np.mean(temp3 * temp2, axis=0).reshape(-1, 1)\n",
    "\n",
    "    return grad\n",
    "\n",
    "#数据组数和维度\n",
    "n, m = X_train.shape\n",
    "\n",
    "#Problem 18\n",
    "w = np.zeros((m, 1))\n",
    "k = 0.001\n",
    "\n",
    "for i in range(2000):\n",
    "    grad = gradient(X_train, w, y_train)\n",
    "    w -= k * grad\n",
    "\n",
    "#计算标签\n",
    "y_test_pred = X_test.dot(w)\n",
    "y_test_pred[y_test_pred > 0] = 1\n",
    "y_test_pred[y_test_pred <= 0] = -1\n",
    "#计算Eout\n",
    "Eout = np.mean(y_test_pred != y_test)\n",
    "#求出误差\n",
    "print(Eout)\n",
    "print(w)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Problem 19"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.22\n",
      "[[-0.00385379]\n",
      " [-0.18914564]\n",
      " [ 0.26625908]\n",
      " [-0.35356593]\n",
      " [ 0.04088776]\n",
      " [-0.3794296 ]\n",
      " [ 0.01982783]\n",
      " [ 0.33391527]\n",
      " [-0.26386754]\n",
      " [ 0.13489328]\n",
      " [ 0.4914191 ]\n",
      " [ 0.08726107]\n",
      " [-0.25537728]\n",
      " [-0.16291797]\n",
      " [ 0.30073678]\n",
      " [ 0.40014954]\n",
      " [ 0.43218808]\n",
      " [-0.46227968]\n",
      " [ 0.43230193]\n",
      " [-0.20786372]\n",
      " [-0.36936337]]\n"
     ]
    }
   ],
   "source": [
    "#Problem 19\n",
    "w = np.zeros((m, 1))\n",
    "k = 0.01\n",
    "\n",
    "for i in range(2000):\n",
    "    grad = gradient(X_train, w, y_train)\n",
    "    w -= k * grad\n",
    "\n",
    "#计算标签\n",
    "y_test_pred = X_test.dot(w)\n",
    "y_test_pred[y_test_pred > 0] = 1\n",
    "y_test_pred[y_test_pred <= 0] = -1\n",
    "#计算Eout\n",
    "Eout = np.mean(y_test_pred != y_test)\n",
    "#求出误差\n",
    "print(Eout)\n",
    "print(w)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Problem 20"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.473\n",
      "[[ 0.01826899]\n",
      " [-0.01308051]\n",
      " [ 0.04072894]\n",
      " [-0.03295698]\n",
      " [ 0.01498363]\n",
      " [-0.03691042]\n",
      " [ 0.01232819]\n",
      " [ 0.04791334]\n",
      " [-0.02244958]\n",
      " [ 0.02470544]\n",
      " [ 0.06878235]\n",
      " [ 0.01897378]\n",
      " [-0.02032107]\n",
      " [-0.00901469]\n",
      " [ 0.04589259]\n",
      " [ 0.05776824]\n",
      " [ 0.06102487]\n",
      " [-0.04756147]\n",
      " [ 0.06035018]\n",
      " [-0.01660574]\n",
      " [-0.03509342]]\n"
     ]
    }
   ],
   "source": [
    "#Problem 20\n",
    "w = np.zeros((m, 1))\n",
    "k = 0.001\n",
    "\n",
    "#计数器\n",
    "j = 0\n",
    "for i in range(2000):\n",
    "    x = X_train[j, :].reshape(1, -1)\n",
    "    s = gradient(x, w, y_train[j])\n",
    "    w -= k * s\n",
    "    #更新下标\n",
    "    j += 1\n",
    "    j = j % n\n",
    "\n",
    "#计算标签\n",
    "y_test_pred = X_test.dot(w)\n",
    "y_test_pred[y_test_pred > 0] = 1\n",
    "y_test_pred[y_test_pred <= 0] = -1\n",
    "#计算sign(Xw)\n",
    "Eout = np.mean(y_test_pred != y_test)\n",
    "#求出误差\n",
    "print(Eout)\n",
    "print(w)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
